package com.ecoolex.ying.space.core.manager;

import com.alibaba.fastjson.JSON;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.CollectorUtil;
import com.ecoolex.ying.space.core.dao.GoodsLabelAssociateDAO;
import com.ecoolex.ying.space.entity.Goods;
import com.ecoolex.ying.space.entity.GoodsLabelAssociate;
import com.ecoolex.ying.space.entity.GoodsLabelAssociate.Column;
import com.ecoolex.ying.space.entity.GoodsLabelAssociateExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class GoodsLabelAssociateManager {
    @Autowired
    private GoodsLabelAssociateDAO dao;

    public long countByLabelId(Integer labelId) {
        GoodsLabelAssociateExample example = new GoodsLabelAssociateExample();
        example.createCriteria().andLabelIdEqualTo(labelId).andDeletedEqualTo(GoodsLabelAssociate.NOT_DELETED);
        return dao.countByExample(example);
    }

    void refresh(Goods goods, String updateUser) {
        List<GoodsLabelAssociate> oldList = queryByGoodsId(goods.getGoodsId());

        List<Integer> labelIds = JSON.parseArray(goods.getLabelIds(), Integer.class);
        if (Check.notNullOrEmpty(labelIds)) {
            List<Integer> distinctLabelIds = labelIds.stream().distinct().collect(Collectors.toList());
            IntStream.range(0, distinctLabelIds.size()).forEach(i -> {
                Integer labelId = distinctLabelIds.get(i);
                GoodsLabelAssociate old = oldList.stream().collect(CollectorUtil.first(label -> label.getLabelId().equals(labelId)));
                if (Check.notNull(old)) {
                    old.setSorting(i + 1);
                    update(old, updateUser);
                    // 移除存在的
                    oldList.remove(old);
                } else {
                    GoodsLabelAssociate record = new GoodsLabelAssociate();
                    record.setGoodsId(goods.getGoodsId());
                    record.setLabelId(labelId);
                    record.setSorting(i + 1);
                    create(record, updateUser);
                }
            });
        }

        oldList.forEach(old -> delete(old, updateUser));
    }

    private void create(GoodsLabelAssociate record, String createUser) {
        record.setDeleted(GoodsLabelAssociate.NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);
    }

    private void update(GoodsLabelAssociate record, String updateUser) {
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record,
                Column.sorting,
                Column.updateUser,
                Column.updateTime);
    }

    private void delete(GoodsLabelAssociate record, String updateUser) {
        record.setDeleted(GoodsLabelAssociate.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        dao.updateByPrimaryKeySelective(record,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    void deleteByGoodsId(Integer goodsId, String updateUser) {
        GoodsLabelAssociate record = new GoodsLabelAssociate();
        record.setDeleted(GoodsLabelAssociate.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        GoodsLabelAssociateExample example = new GoodsLabelAssociateExample();
        example.createCriteria().andGoodsIdEqualTo(goodsId).andDeletedEqualTo(GoodsLabelAssociate.NOT_DELETED);

        dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
    }

    public List<GoodsLabelAssociate> queryByGoodsId(Integer goodsId) {
        GoodsLabelAssociateExample example = new GoodsLabelAssociateExample();
        example.createCriteria().andGoodsIdEqualTo(goodsId).andDeletedEqualTo(GoodsLabelAssociate.NOT_DELETED);
        example.orderBy(Column.sorting.asc());
        return dao.selectByExample(example);
    }
}